#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# vcard_popup.py 
#
#  Copyright (c) 2006 INdT (Instituto Nokia de Technologia)
#
#  Author: Kenneth Rohde Christiansen <kenneth.christiansen@gmail.com>
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
#  USA

import pygtk
pygtk.require("2.0")
import gtk
import gobject
import tapioca

class VCardPopup (gtk.Window):
    """
    A VCard pop up window that shows info about the contacts.
    """

    __gsignals__ = {
        'chat-session-requested' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                    (gobject.TYPE_PYOBJECT,)),
        'voip-session-requested' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                    (gobject.TYPE_PYOBJECT,)),
    }


    def __init__(self, local_contact_store):
        """
        Constructor.
        """

        gtk.Window.__init__(self, gtk.WINDOW_POPUP)

        self.show_timeout_id = 0
        self.hide_timeout_id = 0

        self.local_contact_store = local_contact_store

        self.contact_id = None

        self.width = 250
        self.height = 180

        self.image_width = 100
        self.image_height = 100

        color = gtk.gdk.Color(red=62000, green=62000, blue=62000, pixel=0)
        self.modify_bg(gtk.STATE_NORMAL, color)

        self.vbox = gtk.VBox()

        self.viewport = gtk.Viewport()
        self.viewport.set_shadow_type(gtk.SHADOW_ETCHED_OUT)

        color = gtk.gdk.Color(red=65535, green=65535, blue=65535, pixel=0)
        self.viewport.modify_bg(gtk.STATE_NORMAL, color)

        self.viewport.add(self.vbox)

        self.viewport.show()

        self.add(self.viewport)

        self.hbox = gtk.HBox(False, 4)

        self.set_decorated(True)
        self.set_border_width(0)

        self.set_position(gtk.WIN_POS_NONE)

        self.connect("leave-notify-event", self.on_leave_notify_event)

        self.image = gtk.Image()

        # insure that the image widget has the right size
        # even if the image failed loading.
        self.image.set_size_request(self.image_width, self.image_height)

        self.status_image = gtk.Image()

        self.display_label = gtk.Label("")
        self.display_label.set_size_request(180, -1)
        self.display_label.set_property("can-focus", False)
        self.display_label.set_line_wrap(True)
        self.display_label.set_use_markup(True)
        self.display_label.set_property("xalign", 0)
        self.display_label.set_selectable(True)

        self.id_label = gtk.Label("")
        self.id_label.set_size_request(180, -1)
        self.id_label.set_property("can-focus", False)
        self.id_label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(20000, 20000, 20000))
        self.id_label.set_line_wrap(True)
        self.id_label.set_use_markup(True)
        self.id_label.set_property("xalign", 0)
        self.id_label.set_selectable(True)

        self.status_label = gtk.Label("")
        self.status_label.set_size_request(180, -1)
        self.status_label.set_property("can-focus", False)
        self.status_label.set_line_wrap(True)
        self.status_label.set_use_markup(True)
        self.status_label.set_property("xalign", 0)
        self.status_label.set_selectable(True)

        self.action_bar = gtk.HBox(False, 2)
        self.chat_button = gtk.Button("Initiate Chat")
        self.chat_button.connect("clicked", self.on_chat_button_clicked)

        self.call_button = gtk.Button("Call Contact")
        self.call_button.connect("clicked", self.on_call_button_clicked)

        self.action_bar.pack_start(self.chat_button, False, False, 2)
        self.action_bar.pack_start(self.call_button, False, False, 2)

        self.info_box = gtk.VBox(False, 0)

        self.status_box = gtk.HBox(False, 2)
        self.alg = gtk.Alignment(0.0, 0.0, 0.0, 0.0)
        self.alg.add(self.status_image)

        self.status_box.pack_start(self.alg, True, True, 2)
        self.status_box.pack_start(self.status_label, True, True, 2)

        self.info_box.pack_start(self.display_label, False, True, 2)
        self.info_box.pack_start(self.id_label, False, True, 2)
        self.info_box.pack_start(self.status_box, False, True, 2)

        self.hbox.pack_start(self.info_box, True, True, 2)

        self.alg2 = gtk.Alignment (0.5, 0.5, 0.0, 0.0)
        self.alg2.set_size_request(99, 102)
        self.alg2.add(self.image)
        self.hbox.pack_start(self.alg2, True, True, 2)

        self.vbox.pack_start(self.hbox, True, True, 2);
        self.vbox.pack_start(self.action_bar, False, True, 2)

        self.vbox.set_border_width(4)

        self.connect('event', self.on_event)
        self.vbox.show_all()


    def on_event(self, widget, event):
        """
        Callback hat makes sure to cancel hides when the popup
        has focus.
        """

        if event.type == gtk.gdk.MOTION_NOTIFY:
            self.cancel_hide()
        elif event.type == gtk.gdk.ENTER_NOTIFY:
            self.cancel_hide()


    def delayed_show(self):
        """
        Show the vcard popup after a delay of a second.
        This delayed show might get cancelled.
        """

        def do_show():
            self.show()

            return False

        if self.show_timeout_id > 0:
            gobject.source_remove(self.show_timeout_id)

        self.show_timeout_id = gobject.timeout_add (1000, do_show)


    def cancel_show(self):
        """
        Cancel the delayed show of the vcard popup.
        """

        if self.show_timeout_id > 0:
            gobject.source_remove(self.show_timeout_id)


    def delayed_hide(self):
        """
        Hides the vcard popup after a delay of a second.
        This delayed hide might get cancelled.
        """

        def do_hide():
            self.hide()

            return False

        if self.hide_timeout_id > 0:
            gobject.source_remove(self.hide_timeout_id)

        self.hide_timeout_id = gobject.timeout_add (1000, do_hide)

    def cancel_hide(self):
        """
        Cancels the delayed hide of the vcard popup.
        """

        if self.hide_timeout_id > 0:
            gobject.source_remove(self.hide_timeout_id)

    def on_leave_notify_event(self, widget, event):
        def do_hide():
            self.hide()

            return False

        # Make sure we don't close the popup when the mouse enters the buttons.
        if event.detail != gtk.gdk.NOTIFY_INFERIOR:
            gobject.timeout_add(100, do_hide)


    def on_chat_button_clicked(self, widget):
        if self.contact_id != None:
            self.hide()
            contact = self.local_contact_store.get_contact(self.contact_id)
            self.emit('chat-session-requested', contact)


    def on_call_button_clicked(self, widget):
        if self.contact_id != None:
            self.hide()
            contact = self.local_contact_store.get_contact(self.contact_id)
            self.emit('voip-session-requested', contact)


    def update(self, contact_id):
        self.contact_id = contact_id
        self.display_label.set_markup('<b>%s</b>' % \
                self.local_contact_store.get_alias(contact_id))
        self.id_label.set_markup('<small>(%s)</small>' % self.contact_id)

        if False:
            pass
        #if contact.get_subscription_status() == tapioca.ContactSubscriptionStatus.RemotePending: 
        #    self.status_label.set_text("Authorization pending")
        #    self.status_image.set_from_pixbuf(GtkUtil.LoadPixbufFromIconTheme ("status-pending", 16))
        else:
            self.status_label.set_markup('%s' % \
                    self.local_contact_store.get_presence_message(contact_id))
            self.status_image.set_from_pixbuf(self.local_contact_store.get_presence_icon(contact_id))

        # Convert to grayscale - if offline
        if (self.local_contact_store.get_presence(contact_id) == tapioca.PRESENCE_OFFLINE): 
            temp_avatar = self.local_contact_store.get_avatar_pixbuf(contact_id).copy()
            self.local_contact_store.get_avatar_pixbuf(contact_id).saturate_and_pixelate(temp_avatar, 0.0, False)                    
            self.avatar = temp_avatar

            # FIXME: this should check on the contact capabilities.
            self.chat_button.set_sensitive(False)
            self.call_button.set_sensitive(False)
        else:
            self.avatar = self.local_contact_store.get_avatar_pixbuf(contact_id)

            self.chat_button.set_sensitive(True)

            contact = self.local_contact_store.get_contact(contact_id)

            if contact.get_capabilities() & tapioca.CAPABILITY_AUDIO:
                self.call_button.set_sensitive(True)
            else:
                self.call_button.set_sensitive(False)

        self.image.set_from_pixbuf(self.avatar)

        self.queue_resize()


if __name__ == "__main__":
    window = VCardPopup()
    window.show_all()

    gtk.main()
